package com.example.object.game;

import android.content.Context;
import android.util.Log;

import com.example.bounce.R;
import com.example.globject.GLSquare;
import com.example.object.GameShape;

import org.jbox2d.collision.shapes.PolygonShape;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.BodyDef;
import org.jbox2d.dynamics.BodyType;
import org.jbox2d.dynamics.FixtureDef;
import org.jbox2d.dynamics.World;
import org.jbox2d.dynamics.joints.Joint;
import org.jbox2d.dynamics.joints.RopeJointDef;

/**
 * Created by Lucas on 06/07/13.
 */
public class Elastic extends GameShape {

    private GLSquare _glRope;
    private BodyDef _bodyDef;
    private Body _body;

    private float _width, _height;
    private float _size;
    private final String TAG = "Elastic";
    private Joint _joint;

    public Elastic(Context context, float xCenter, float yCenter, float width, float height){
        Log.i(TAG, "Elastic constructor");
        _handlerInitiate = false;
        // doesn't need to be initialized
        _userData = 0;
        _width = width; _height = height;
        //_size = size;
        _glRope = new GLSquare(context, xCenter, yCenter, height, width, R.raw.rope);

        // create definition
        _bodyDef = new BodyDef();

        _bodyDef.position.set(new Vec2(xCenter, yCenter));
        _bodyDef.type = BodyType.DYNAMIC;
    }

    public void addToWorld(World world){
        float halfWidth = _width/2f;
        float halfHeight = _height/2f;
        // need to reverse the width and height for some reason
        PolygonShape shape = new PolygonShape();
        shape.setAsBox(halfHeight, halfWidth*2f, new Vec2(halfHeight, 0), 0f);
        _body = world.createBody(_bodyDef);
        // body features like density, restitution, ....
        FixtureDef fd = new FixtureDef();
        fd.density = 0f;
        fd.restitution = 0.3f;
        fd.friction = 0.0f;
        fd.shape = shape;
        _body.createFixture(fd);

    }

    public void jointTo(Elastic elastic, World world){
        RopeJointDef jointDef = new RopeJointDef();
        jointDef.bodyA = _body;
        jointDef.bodyB = elastic.getBody();
        jointDef.localAnchorA.set(new Vec2(0,0));
        jointDef.localAnchorB.set(new Vec2(0,0));
        jointDef.maxLength = 0.1f;
        jointDef.collideConnected = false;
        world.createJoint(jointDef);
    }

    public void jointTo(Anchor anchor, World world){
        RopeJointDef jointDef = new RopeJointDef();
        jointDef.bodyA = _body;
        jointDef.bodyB = anchor.getBody();
        jointDef.localAnchorA.set(new Vec2(0,0));
        jointDef.localAnchorB.set(new Vec2(0,0));
        jointDef.maxLength = 0.1f;
        jointDef.collideConnected = false;
        world.createJoint(jointDef);

    }

    public void setGLHandler(int positionHandle, int textureHandle, int MVPMatrixHandle,
                             float vMatrix[], float projMatrix[]){
        _glRope.setGLHandler(positionHandle, textureHandle, MVPMatrixHandle, vMatrix, projMatrix, null);
        _handlerInitiate = true;
    }

    @Override
    public void moveTo(float toX, float toY) {
        _glRope.moveTo(toX, toY);
    }

    @Override
    public void calculateNextCoordinate() {
        //Log.d(TAG, "Calculate next coordinates");
        Vec2 position =  _body.getWorldCenter();
        moveTo(position.x, position.y);
    }

    /**
     * return a boolean to know if the object is movable
     *
     * @return true
     */
    @Override
    public boolean isMovable() {
        return true;
    }

    @Override
    public boolean isTouched(Vec2 touch) {
        return false;
    }

    @Override
    public Body getBody() {
        return _body;
    }

    @Override
    public void draw(){
        _glRope.draw();
    }

    public String toString(){
        return "\n glSquare: " + _glRope.toString();
    }

    public GLSquare getGLSquare(){
        return _glRope;
    }
}
